﻿using MyCryptoChat.BusinessEntities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace MyCryptoChat
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        private static string _saveChatroomsFilePath
        {
            get { return Path.Combine(HttpRuntime.AppDomainAppPath, "App_Data", Constants.SAVE_CHATROOMS_FILE_NAME); }
        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();

            var cleanChatroomsThread = new Thread(CleanChatrooms);
            cleanChatroomsThread.IsBackground = true;
            cleanChatroomsThread.Start();

            Application["CleanChatroomsThread"] = cleanChatroomsThread;
        }

        private void CleanChatrooms(object obj)
        {
            while (true)
            {
                Thread.Sleep(60000);

                var keysToDelete = new List<string>();
                foreach (var key in Application.AllKeys)
                {
                    var chatRoom = Application[key] as ChatRoom;
                    if (chatRoom != null)
                    {
                        if (chatRoom.DateCreation.AddMinutes(chatRoom.NbMinutesToLive) < DateTime.UtcNow)
                        {
                            keysToDelete.Add(key);
                        }
                    }
                }
                foreach (var keyToDelete in keysToDelete)
                {
                    Application.Remove(keyToDelete);
                }
            }
        }

        protected void Application_End()
        {
            try
            {
                var cleanChatroomsThread = (Thread)Application["CleanChatroomsThread"];
                if (cleanChatroomsThread != null && cleanChatroomsThread.IsAlive == true)
                {
                    cleanChatroomsThread.Abort();
                }

                SaveChatrooms();
            }
            catch
            {

            }
        }

        private void SaveChatrooms()
        {
            var chatRooms = new List<ChatRoom>();

            foreach (var key in Application.AllKeys)
            {
                var chatRoom = Application[key] as ChatRoom;
                if (chatRoom != null)
                {
                    chatRoom.Id = key;
                    chatRooms.Add(chatRoom);
                }

                if (chatRooms.Any())
                {
                    SaveAsBin(chatRooms, _saveChatroomsFilePath);
                }
            }
        }

        private static void SaveAsBin(object toSave, string path)
        {
            var formatter = new BinaryFormatter();
            FileStream flux = null;
            try
            {
                flux = new FileStream(path, FileMode.Create, FileAccess.Write);
                formatter.Serialize(flux, toSave);
                flux.Flush();
            }
            catch { }
            finally
            {
                if (flux != null)
                    flux.Close();
            }
        }
    }
}